using System;
using System.Drawing;
using System.Collections.Generic;
using System.Text;
using Northwoods.Go;

namespace Workflows.Diagrams
{
    /// <summary></summary>
    [Serializable]
    public class ActivityPort : GoPort
    {
        #region members
        public const int ChangedMaxLinks = LastChangedHint + 12121;
        private int myMaxLinks = 999999;
        #endregion

        #region ctor
        /// <summary></summary>
        public ActivityPort()
        {
            this.Style = GoPortStyle.Ellipse;
            this.Pen = Pens.Black;
            this.Brush = null;
            this.Size = new SizeF(8, 8);
            this.FromSpot = NoSpot;
            this.ToSpot = NoSpot;
            this.IsValidFrom = true;
            this.IsValidTo = true;
        }
        #endregion

        #region properties
        /// <summary></summary>
        public ActivityNode ActivityNode
        {
            get
            {
                return this.Parent as ActivityNode;
            }
        }

        /// <summary></summary>
        public GoImage PortImage
        {
            get
            {
                return (GoImage)this.PortObject;
            }
            set
            {
                this.PortObject = value;
                if (value == null)
                {
                    this.Style = GoPortStyle.Ellipse;
                }
                else
                {
                    this.Style = GoPortStyle.Object;
                }
            }
        }

        /// <summary></summary>
        public int MaxLinks
        {
            get
            {
                return this.myMaxLinks;
            }
            set
            {
                int old = this.myMaxLinks;
                if ((old == value) && (value >= 0))
                {
                    this.myMaxLinks = value;
                    this.Changed(ChangedMaxLinks, old, null, NullRect, value, null, NullRect);
                }

            }
        }

        /// <summary></summary>
        public override bool CanLinkFrom()
        {
            return (base.CanLinkFrom() && this.LinksCount < this.MaxLinks);
        }
        #endregion

        #region overrides handler
        /// <summary></summary>
        public override void OnLinkChanged(IGoLink l, int subhint, int oldI, object oldVal, RectangleF oldRect, int newI, object newVal, RectangleF newRect)
        {
            if (subhint == GoPort.ChangedAddedLink || subhint == GoPort.ChangedRemovedLink)
            {
                int numLinks = this.LinksCount;
                if (numLinks <= 0)
                {
                    this.Style = GoPortStyle.Ellipse;
                    this.ToSpot = this.FromSpot;
                }
                else
                {
                    this.Style = GoPortStyle.Triangle;
                    foreach(IGoLink link in this.Links)
                    {
                        if (link.FromPort == this)
                        {
                            this.ToSpot = SpotOpposite(this.FromSpot);
                        }
                        else
                        {
                            this.ToSpot = this.FromSpot;
                        }
                        break;
                    }
                }
            }
        }

        /// <summary></summary>
        public override void ChangeValue(GoChangedEventArgs e, bool undo)
        {
            switch (e.SubHint)
            {
                case ChangedMaxLinks:
                    this.MaxLinks = e.GetInt(undo);
                    break;
                default:
                    base.ChangeValue(e, undo);
                    break;
            }
        }
        #endregion
    }
}
